package bhbt.taglib.tdformtag;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import javax.servlet.jsp.JspWriter;
import javax.servlet.jsp.tagext.BodyContent;
import javax.servlet.jsp.tagext.BodyTagSupport;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;


/**
 * Auth: qiyh
 */
public class TDFormTag extends BodyTagSupport {

	// ---------------------------------------------------------------- tag parameters

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	private String beanNames = null;
	

	public void setBeans(String v) {
		beanNames = v;
	}

	public String getBeans() {
		return beanNames;
	}

	private String scopes = "request";//默认从request中取

	public void setScopes(String v) {
		scopes = v;
	}

	public String getScopes() {
		return scopes;
	}


	// ---------------------------------------------------------------- tag methods

	private HashMap beansValues = null;

	public int doStartTag() {
		beansValues = new HashMap();
		if(null != beanNames) {
			String[] bArr = beanNames.split(",");
			for (String b : bArr) {
				Object bean = getBeanFromScope(b);
				if (bean != null) {
					Map valueMap = (Map) TDFormTagUtil.getAllProperties(bean);
					beansValues.putAll(valueMap);
				}
			}
		}else{
			Map properties = pageContext.getRequest().getParameterMap();
			Iterator entries = properties.entrySet().iterator();
			while (entries.hasNext()) {
				Map.Entry entry = (Map.Entry) entries.next();
				String name = (String) entry.getKey();
				Object valueObj = entry.getValue();
				if(null == valueObj){
					beansValues.put(name, "");
					continue;
				}
				if(valueObj instanceof String[]){
					String[] values = (String[])valueObj;
					if(1 == values.length){
						valueObj = values[0];
					}
				}
				beansValues.put(name, valueObj);
			}
		}
		return EVAL_BODY_AGAIN;
	}

	public int doAfterBody() {
		BodyContent body = getBodyContent();
		try{
			JspWriter out = body.getEnclosingWriter();
			String bodytext = body.getString();
			bodytext = populateForm(bodytext, beansValues);
			out.print(bodytext);
		} catch (Exception ex) {
			ex.printStackTrace();
		}
		return SKIP_BODY;
	}


	public int doEndTag() {
		return EVAL_PAGE;
	}


	// ---------------------------------------------------------------- populate

	private String populateForm(String html, HashMap values) {
		int i = 0, s = 0;
		StringBuffer result = new StringBuffer(html.length());
		String currentSelectName = null;
		while (true) {
			// find starting tag
			i =	html.indexOf('<', s);
			if (i == -1) {
				result.append(html.substring(s));
				break;		// input tag not found
			}
			result.append(html.substring(s, i));	// tag found, all before tag is stored
			s = i;

			// find closing tag
			i =	html.indexOf('>', i);
			if (i == -1) {
				result.append(html.substring(s));
				break;		// closing tag not found
			}
			i++;

			// match tags
			String tag = html.substring(s, i);
//			System.out.println(tag);
			String tagName = TDFormTagUtil.getTagName(tag);
			String tagValue = TDFormTagUtil.getAttribute(tag, "value");
			String tagType = TDFormTagUtil.getAttribute(tag, "type");
			if (tagName.equalsIgnoreCase("input") == true) {
				if(null != tagValue){
					s = i;
					if(!tagType.equals("checkbox") && !tagType.equals("radio")){
						result.append(tag);
						continue;
					}
				}
				if (tagType != null) {
					String name = TDFormTagUtil.getAttribute(tag, "name");
					Object value = null;
					if(values.containsKey(name)){
						value = values.get(name);
						tagType = tagType.toLowerCase();
					} else{
						//如果bean中不包含次name的属性值，则从scope中获取
						value = getBeanFromScope(name);
					}
					if (tagType.equals("text")) {
						tag = TDFormTagUtil.addAttribute(tag, "value", value);
					} else if (tagType.equals("hidden")) {
						tag = TDFormTagUtil.addAttribute(tag, "value", value);
					} else if (tagType.equals("image")) {
						tag = TDFormTagUtil.addAttribute(tag, "value", value);
					} else if (tagType.equals("password")) {
						tag = TDFormTagUtil.addAttribute(tag, "value", value);
					} else if (tagType.equals("checkbox")) {
						if (tagValue == null) {
							tagValue = "true";
						}
						if (tagValue.equals(value)) {
							tag = TDFormTagUtil.addAttribute(tag, "checked");
						}
					} else if (tagType.equals("radio")) {
						tagValue = TDFormTagUtil.getAttribute(tag, "value");
						if (tagValue != null) {
							if (tagValue.equals(value)) {
								tag = TDFormTagUtil.addAttribute(tag, "checked");
							}
						}
					}
				}
			} else if (tagName.equalsIgnoreCase("textarea") == true) {
				if(null != tagValue){
					result.append(tag);
					s = i;
					continue;
				}
				String name = TDFormTagUtil.getAttribute(tag, "name");
				if (values.containsKey(name)) {
					Object value = values.get(name);
					if (value != null) {
						//tag += ServletUtil.encodeHtml(StringUtil.toString(value));
						tag += TDFormTagUtil.encode(TDFormTagUtil.toString(value));
					}
				}
			} else if (tagName.equalsIgnoreCase("select") == true) {
				currentSelectName = TDFormTagUtil.getAttribute(tag, "name");
			} else if (tagName.equalsIgnoreCase("/select") == true) {
				currentSelectName = null;
			} else if (tagName.equalsIgnoreCase("option") == true) {
				if (currentSelectName != null) {
					tagValue = TDFormTagUtil.getAttribute(tag, "value");
					if(tagValue == null){
						tagValue = TDFormTagUtil.toString(values.get(currentSelectName));
					}
					if (tagValue != null) {
						if (values.containsKey(currentSelectName)) {
							Object vals = values.get(currentSelectName);
							if (vals != null) {
								if (vals.getClass().isArray() == false) {
									String value = TDFormTagUtil.toString(vals);
									if (value.equals(tagValue)) {
										tag = TDFormTagUtil.addAttribute(tag, "selected");
									}
								} else {
									String vs[] = TDFormTagUtil.convertToStringArray(vals);
									for (int k = 0; k < vs.length; k++) {
										String vsk = vs[k];
										if (vsk != null) {
											if (vsk.equals(tagValue)) {
												tag = TDFormTagUtil.addAttribute(tag, "selected");
											}
										}
									}
								}
							}
						}
					}
				}
			}
			result.append(tag);
			s = i;
		}
		return result.toString();
	}

	private Object getBeanFromScope(String beanName){
		Object bean = null;
		HttpServletRequest request = (HttpServletRequest) pageContext.getRequest();
		HttpSession session = (HttpSession) pageContext.getSession();
		String[] scopeArr = scopes.toLowerCase().split(",");
		for(int i=scopeArr.length-1; i>-1; i--){
			String s = scopeArr[i];
			if(s.equals("page")){
				bean = pageContext.getAttribute(beanName);
			} else if (s.equals("request")) {
				bean = request.getAttribute(beanName);
			} else if (s.equals("session")) {
				bean = session.getAttribute(beanName);
			}
			if(bean != null){
				break;
			}
		}
		return bean;
	}
	
}
